package com.tvunetworks.center.user.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.github.pagehelper.PageInfo;
import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.exception.ServerException;
import com.tvunetworks.center.common.model.CommandParam;
import com.tvunetworks.center.common.model.LoginUser;
import com.tvunetworks.center.common.model.param.EmailParam;
import com.tvunetworks.center.common.model.param.UpdateUserEmailParam;
import com.tvunetworks.center.common.model.param.UserIdParam;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.user.annotation.Logined;
import com.tvunetworks.center.user.model.User;
import com.tvunetworks.center.user.model.json.ExcelData;
import com.tvunetworks.center.user.model.param.*;
import com.tvunetworks.center.user.model.vo.CheckUserVo;
import com.tvunetworks.center.user.model.vo.GetUserByRoleIdVo;
import com.tvunetworks.center.user.model.vo.PageUserVo;
import com.tvunetworks.center.user.model.vo.UserIdWithEmail;
import com.tvunetworks.center.user.service.UserService;
import com.tvunetworks.center.user.service.feign.DeviceFeignService;
import com.tvunetworks.center.user.service.feign.RwsFeignService;
import com.tvunetworks.center.user.service.feign.UserAuthFeignService;
import com.tvunetworks.center.user.util.ExcelUtil;
import com.tvunetworks.center.user.util.GetSessionUtils;
import com.tvunetworks.center.user.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @program: tvucc-user
 * @description: UserController
 * @author lebronchen
 * @create: 2019-02-28 16:54
 **/
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RwsFeignService rwsFeignService;
    @Autowired
    private DeviceFeignService deviceFeignService;
    @Autowired
    private UserAuthFeignService userAuthFeignService;


    @Value("${newuserservice.redirect.url}")
    private String userserviceUrl;
    @Value("${tvucc.url}")
    private String tvuccUrl;
    @Value("${servicenameinauthorizationservice}")
    private String authServerName;
    @Value("${newuserservice.login.url}")
    private String newuserserviceLoginUrl;
    @Value("${newuserservice.name}")
    private String newuserserviceName;

    /**
     *
     * @param loginUser loginUser
     * @param param param
     * @return Result
     */
    @PostMapping("/getSessionByEmail")
    public Result getSessionByEmail(@Logined LoginUser loginUser, @RequestBody EmailParam param){
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        String role = loginUser.getRole();
        if (LocalConstant.UserRole.ADMIN.equals(role) || LocalConstant.UserRole.USER.equals(role)) {
            return ResultUtil.noAuthority();
        }
        String email = param.getEmail();
        if (StringUtils.isEmpty(email)) {
            return ResultUtil.paramError();
        }
        return userService.getSessionByEmail(email);
    }

    /**
     * 退出登录接口
     * @param loginUser loginUser
     * @param request request 请求头
     * @return Result
     */
    @GetMapping("/logout")
    public Result<Object> logout(@Logined LoginUser loginUser,HttpServletRequest request){
       String token = GetSessionUtils.getToken(request);
       //String token = request.getHeader(LocalConstant.ACCESS_TOKEN_KEY);
        if (StringUtils.isBlank(token)) {
            return ResultUtil.noLogin();
        }

        userAuthFeignService.logOut(token);
        //    userService.logout(token);

        String redirectUrl = new StringBuilder(userserviceUrl).append("?url=https://").append(tvuccUrl).append("&serviceName=").append(authServerName).toString();
        String ccUrl="";
        String userServiceUrl="";
        try {
            log.error("==logout=newuserserviceLoginUrl1===="+newuserserviceLoginUrl);
            log.error("=logout==loginUser.getEmail()1===="+loginUser.getEmail());
            List<Map<String, String>> mapList = JsonUtil.toObject(newuserserviceLoginUrl,new TypeReference<List<Map<String, String>>>() {});
            log.error("==logout=newuserserviceLoginUrl2===="+newuserserviceLoginUrl);
            log.error("=logout==loginUser.getEmail()2===="+loginUser.getEmail());
            String[] emailArr=loginUser.getEmail().split("@");
            String logoutKey="";
            if(emailArr.length==2){
                logoutKey=emailArr[1];
            }
            log.error("==logout=logoutKey===="+logoutKey);
            if(StringUtils.isNotBlank(logoutKey)){
                for(Map<String, String> map :mapList){
                    String emailKey = map.get("email");
                    log.error("=logout==emailKey===="+emailKey);
                    log.error("=logout==emailKey.contains(logoutKey)===="+emailKey.contains(logoutKey));
                    if(emailKey.contains(logoutKey)){
                        ccUrl=map.get("cc");
                        userServiceUrl=map.get("userservice");
                        break;
                    }
                }
            }
            log.error("=logout==userServiceUrl===="+userServiceUrl);
            log.error("=logout==ccUrl===="+ccUrl);

            if(StringUtils.isNotBlank(ccUrl) && StringUtils.isNotBlank(userServiceUrl) ){
                log.error("=logout==StringUtils.isNotBlank(ccUrl) && StringUtils.isNotBlank(userServiceUrl)===="+StringUtils.isNotBlank(ccUrl)+"====="+ StringUtils.isNotBlank(userServiceUrl));
                redirectUrl= new StringBuilder(userServiceUrl+"/"+newuserserviceName).append("?url=").append("http://"+ccUrl+"/tvucc").append("&serviceName=").append(authServerName).toString();

            }
            log.error("=logout==redirectUrl1===="+redirectUrl);
        } catch (IOException e) {
            log.error("logout==redirectUrl exception==",e);
            log.error("msg:{},e:{}",e.getMessage(),e);
        }
        log.error("=logout==redirectUrl2===="+redirectUrl);
        Map logoutMap = new HashMap();
        logoutMap.put("redirectUrl",redirectUrl);
        return ResultUtil.success(logoutMap);
    }

    /**
     *
     * @param loginUser loginUser
     * @param param param
     * @param pageNum pageNum
     * @param pageSize pageSize
     * @return Result
     */
    @GetMapping("/page")
    public Result pageUser(@Logined LoginUser loginUser, SearchUserParam param, @RequestParam(defaultValue="1") Integer pageNum, @RequestParam(defaultValue="10") Integer pageSize){
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        PageInfo<PageUserVo> userPageInfo = userService.pageUser(loginUser, param, pageNum, pageSize);
        return ResultUtil.success(userPageInfo);
    }

    /**
     * 列出拥有feature用户 导出Excel
     * @param param param
     * @param response response
     * @param session session
     */
    @GetMapping("/exportUser")
    public void exportUser(HttpServletResponse response, SearchUserParam param, @RequestParam String session) {
        if (StringUtils.isEmpty(param.getAccountType())) {
            param.setAccountType(param.getRole());
        }
        LoginUser loginUser = (LoginUser) redisUtil.get(LocalConstant.REDIS_LOGIN_USER_KEY + session);
        if (loginUser == null) {
            throw new ServerException(ResultUtil.noLogin());
        }
        if (!LocalConstant.UserRole.SUPPORT.equals(loginUser.getRole())) {
            throw new ServerException(ResultUtil.noAuthority());
        }
        if (!LocalConstant.UserRole.ADMIN.equals(param.getAccountType()) && !LocalConstant.UserRole.USER.equals(param.getAccountType())) {
            throw new ServerException(ResultUtil.noAuthority());
        }
        ExcelData excelData = userService.exportUser(loginUser, param);
        try {
            ExcelUtil.exportExcel(response,"User", excelData);
        } catch (Exception e) {
            throw new ServerException(ResultUtil.error("81001001","Export user excel fail!"));
        }
    }


    /**
     *  查询admin用户的userId和email，用于Support创建User的时候选择父亲
     * @param email email
     * @param pageNum pageNum
     * @param pageSize pageSize
     * @return Result
     */
    @GetMapping("/pageAdminIdAndEmail")
    public Result<Object> pageAdminIdAndEmail(String email, @RequestParam(defaultValue="1") Integer pageNum, @RequestParam(defaultValue="50") Integer pageSize){
        PageInfo<UserIdWithEmail> userPageInfo = userService.pageAdminIdAndEmail(email, pageNum, pageSize);
        return ResultUtil.success(userPageInfo);
    }

    /**
     * 设置用户 Role
     * @param userId userId
     * @param accountType accountType
     * @param loginUser 当前登录账号信息
     * @return Result
     */
    @PostMapping("/setRole")
    public Result<Object> setRole(@Logined LoginUser loginUser,@RequestParam String userId, @RequestParam String accountType){

        int result = userService.setRole(userId, accountType,loginUser);
        if (result == 1) {
            return ResultUtil.error("81000401", "User not Exist");
        } else if (result == 2) {
            return ResultUtil.error("81000402", "User role in the current state");
        }
        return ResultUtil.success();
    }

    /**
     * 设置用户是否可用
     * @param userId userId
     * @param active active
     * @return Result
     */
    @PostMapping("/setActive")
    public Result<Object> setActive(@RequestParam String userId, @RequestParam String active){
        int result = userService.setActive(userId, active);
        if (result == 1) {
            return ResultUtil.error("81000501", "User not Exist");
        } else if (result == 2) {
            return ResultUtil.error("81000502", "User active in the current state");
        } else if (result == 3) {
            return ResultUtil.error("81000503", "UserService set active failed");
        } else if (result == 4) {
            return ResultUtil.error("81000504", "UserService interface error");
        }
        return ResultUtil.success();
    }

    /**
     * 创建用户
     * @param loginUser loginUser
     * @param createUserParam createUserParam
     * @param  request request
     * @return Result
     */
    @PostMapping("/createUser")
    public Result<String> createUser(@Logined LoginUser loginUser, @Valid CreateUserParam createUserParam, HttpServletRequest request){
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        String session = GetSessionUtils.getToken(request);
     //  String session = request.getHeader(LocalConstant.ACCESS_TOKEN_KEY);
        createUserParam.setSession(session);
        return userService.createUser(loginUser, createUserParam);
    }

    /**
     * check 用户在cc和userservice的存在情况  仅用于 Setting -> Account 页面创建用户前的校验
     * @param email email
     * @param  loginUser loginUser
     * @param  request request
     * @return Result
     */
    @GetMapping("/checkUser")
    public Result<Object> checkUser(@Logined LoginUser loginUser, HttpServletRequest request, String email){
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        String session = GetSessionUtils.getToken(request);
      //  String session = request.getHeader(LocalConstant.ACCESS_TOKEN_KEY);
        CheckUserVo result = userService.checkUser(loginUser, session, email);
        return ResultUtil.success(result);
    }

    /**
     *
     * @param loginUser loginUser
     * @return Result
     * @throws IOException 編譯一場
     */
    @GetMapping("/settingTab")
    public Result<Object> getSettingTab(@Logined LoginUser loginUser) throws IOException {
        if(loginUser == null) {
            return ResultUtil.noLogin();
        }

        if(StringUtils.isEmpty(loginUser.getRole())){
            log.error("settingTab role is empty [{}]", JsonUtil.toJsonStr(loginUser));
        }

        String tab = userService.getSettingTab(loginUser.getRole());
        return ResultUtil.success(tab);
    }

    /**
     *
     * @return Result
     */
    @GetMapping("/list")
    public Result<Object> listUser(){
        List<User> users = userService.selectAll();
        return ResultUtil.success(users);
    }


    /**
     *
     * @return Result
     */
    @GetMapping("/list2")
    public Result<Object> listUser2(){
        log.info("参数:{},参数:{},参数:{}",1,2,3);
        List<User> users = userService.listUser();
        return ResultUtil.success(users);
    }

    /**
     *
     * @return Result
     */
    @GetMapping("/testRedis")
    public Result<Object> testRedis(){
     //   Object a = redisUtil.get("a");
       // int b = 1/0;
        return ResultUtil.success();
    }

    /**
     *
     * @param id id
     * @return Result
     */
    @DeleteMapping("/{id}")
    public Result<Object> deleteUser(@PathVariable(value = "id") String id){
        System.out.println(id);
        return ResultUtil.success(id);
    }

    /**
     *
     * @param user user
     * @return Result
     */
    @PutMapping()
    public Result<Object> updateUser(User user){
        System.out.println(user);
        return ResultUtil.success(user);
    }

    /**
     *
     * @return Result
     */
    @GetMapping("/setUser")
    public Result<Object> setUser(){
        LoginUser loginUser = new LoginUser();
        loginUser.setId("id");
        loginUser.setEmail("email");
        redisUtil.set(LocalConstant.REDIS_LOGIN_USER_KEY + "aaa", loginUser);
        return ResultUtil.success();
    }

    /**
     *
     * @param loginUser loginUser
     * @return Result
     */
    @GetMapping("/testUser")
    public Result<Object> testUser(@Logined LoginUser loginUser){

        return ResultUtil.success(loginUser);
    }

    /**
     *
     * @param rid rid
     * @return  Result
     */
    @GetMapping("/testRShareInfo")
    public Result<String> testRShareInfo(@RequestParam(required = true) String rid){
        CommandParam commandParam = new CommandParam(rid, "2152870656", "101");
        return rwsFeignService.command(commandParam);
    }

    /**
     *
     * @param peerId peerId
     * @return Device
     */
    @GetMapping("/getDevice")
    public Device getDevice(@RequestParam String peerId){
        return deviceFeignService.getMemDevice(peerId);
    }

    /**
     *
     * @return Result
     */
    @GetMapping("/initOriginParam")
    public Result<Object> initOriginParam(){
        return userService.initOriginParam();
    }

    /**
     *
     * @param loginUser loginUser
     * @param param param
     * @return Result
     */
    @PostMapping("/moveUserToOtherAdmin")
    public Result moveUserToOtherAdmin(@Logined LoginUser loginUser, @Valid @RequestBody MoveUserToOtherAdminParam param) {
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        param.setLoginUserId(loginUser.getId());
        int result = userService.moveUserToOtherAdmin(param);
        if (result == 1) {
            return ResultUtil.error("81002201", "Customer user not exist");
        }
        if (result == 2) {
            return ResultUtil.error("81002202", "Customer user not a user");
        }
        if (result == 3) {
            return ResultUtil.error("81002203", "Admin user not exist");
        }
        if (result == 4) {
            return ResultUtil.error("81002204", "Admin user not a admin");
        }
        if (result == 5) {
            return ResultUtil.error("81002205", "Customer user already belong to admin user");
        }
        return ResultUtil.success();
    }

    /**
     *
     * @param param param
     * @return Result
     */
    @PostMapping("/getParentUser")
    public Result getParentUser(@Valid @RequestBody UserIdParam param){
        User user = userService.getParentUser(param.getUserId());
        return ResultUtil.success(user);
    }

    /**
     *
     * @param loginUser loginUser
     * @param param param
     * @return Result
     */
    @PostMapping("/updateUserEmail")
    public Result updateUserEmail(@Logined LoginUser loginUser, @RequestBody @Valid UpdateUserEmailParam param){
        userService.updateUserEmail(loginUser, param);
        return ResultUtil.success();
    }

    /**
     *
     * @param loginUser loginUser
     * @param param param
     * @return Result
     */
    @PostMapping("/delelteUser")
    public Result delelteUser(@Logined LoginUser loginUser,@RequestBody @Valid DeleteAccoutParam param){
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        try {
            userService.deleteAccout(loginUser,param.getUserId());

        } catch (Exception e) {
            log.error(e.getMessage(),e);
            return ResultUtil.exception(e);
        }
        return ResultUtil.success();
    }

    /**
     *
     * @param loginUser loginUser
     * @param param param
     * @return Result
     */
    @PostMapping("/deleteUser")
    public Result deleteUser(@Logined LoginUser loginUser,@RequestBody @Valid DeleteAccoutParam param){
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        userService.invalidateUser(loginUser, param.getUserId(), param.isDeleteSonAccountFlag());
        return ResultUtil.success();
    }

    /**
     * 根据admin账号的id获取其所有的子账号
     * @param loginUser loginUser
     * @param param param
     * @return Result
     */
    @PostMapping("/pageSonUser")
    public Result pageSonUserByParentUserId(@Logined LoginUser loginUser,@RequestBody @Valid PageSonUserParam param){
        if (loginUser == null) {
            return ResultUtil.noLogin();
        }
        PageInfo<GetUserByRoleIdVo> userVoPageInfo = userService.pageSonUserByParentUserId(param);
        return ResultUtil.success(userVoPageInfo);
    }
}
